<!DOCTYPE html>
<html lang="zh-CN">





<head>
  <meta charset="UTF-8">
  <link rel="apple-touch-icon" sizes="76x76" href="/myblog/img/apple-touch-icon.png">
  <link rel="icon" type="image/png" href="/myblog/img/favicon.png">
  <meta name="viewport"
        content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie=edge">
  
  <meta name="theme-color" content="#2f4154">
  <meta name="description" content="TakCode Blog">
  <meta name="author" content="谢芃">
  <meta name="keywords" content="">
  <title>JS DOM BOM操作 - TakCode</title>

  <link  rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/5.12.1/css/all.min.css" />
<link  rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/css/bootstrap.min.css" />
<link  rel="stylesheet" href="https://cdn.staticfile.org/mdbootstrap/4.13.0/css/mdb.min.css" />
<link  rel="stylesheet" href="https://cdn.staticfile.org/github-markdown-css/3.0.1/github-markdown.min.css" />

<link rel="stylesheet" href="//at.alicdn.com/t/font_1067060_qzomjdt8bmp.css">



  <link  rel="stylesheet" href="/myblog/lib/prettify/tomorrow-night-eighties.min.css" />

<link  rel="stylesheet" href="/myblog/css/main.css" />


  <link defer rel="stylesheet" href="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.css" />


<!-- 自定义样式保持在最底部 -->


<meta name="generator" content="Hexo 4.2.0"></head>


<body>
  <header style="height: 70vh;">
    <nav id="navbar" class="navbar fixed-top  navbar-expand-lg navbar-dark scrolling-navbar">
  <div class="container">
    <a class="navbar-brand"
       href="/myblog/">&nbsp;<strong>TakCode</strong>&nbsp;</a>

    <button id="navbar-toggler-btn" class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarSupportedContent"
            aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
      <div class="animated-icon"><span></span><span></span><span></span></div>
    </button>

    <!-- Collapsible content -->
    <div class="collapse navbar-collapse" id="navbarSupportedContent">
      <ul class="navbar-nav ml-auto text-center">
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/">首页</a>
          </li>
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/archives/">归档</a>
          </li>
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/categories/">分类</a>
          </li>
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/tags/">标签</a>
          </li>
        
          
          
          
          
          <li class="nav-item">
            <a class="nav-link" href="/myblog/about/">关于</a>
          </li>
        
        
          <li class="nav-item" id="search-btn">
            <a class="nav-link" data-toggle="modal" data-target="#modalSearch">&nbsp;&nbsp;<i
                class="iconfont icon-search"></i>&nbsp;&nbsp;</a>
          </li>
        
      </ul>
    </div>
  </div>
</nav>

    <div class="view intro-2" id="background" parallax=true
         style="background: url('/myblog/img/default.png') no-repeat center center;
           background-size: cover;">
      <div class="full-bg-img">
        <div class="mask rgba-black-light flex-center">
          <div class="container text-center white-text fadeInUp">
            <span class="h2" id="subtitle">
              
            </span>

            
              
                <p class="mt-3 post-meta">
                  <i class="fas fa-calendar-alt" aria-hidden="true"></i>
                  星期五, 三月 15日 2019, 7:56 晚上
                </p>
              

              <p class="mt-1">
                
                  
                  <span class="post-meta">
                    <i class="far fa-chart-bar"></i>
                    11.9k 字
                  </span>
                

                
                  
                  <span class="post-meta">
                      <i class="far fa-clock"></i>
                      51 分钟
                  </span>
                

                
              </p>
            
          </div>

          
        </div>
      </div>
    </div>
  </header>

  <main>
    
      

<div class="container-fluid">
  <div class="row">
    <div class="d-none d-lg-block col-lg-2"></div>
    <div class="col-lg-8 nopadding-md">
      <div class="container nopadding-md" id="board-ctn">
        <div class="py-5 z-depth-3" id="board">
          <div class="post-content mx-auto" id="post">
            
            <div class="markdown-body">
              <p>JS DOM BOM操作学习笔记</p>
<a id="more"></a>

<pre><code class="mermaid">graph TD
A[JS]
A --&gt;|JS语法| D[ECMAScript]
A --&gt;|页面文档对象模型| E[DOM]
A --&gt;|浏览器对象模型| F[BOM]</code></pre>
<h1 id="API"><a href="#API" class="headerlink" title="API"></a>API</h1><p>应用程序编程接口，就是一个工具，以便于能轻松实现想要完成的功能</p>
<h1 id="Web-API"><a href="#Web-API" class="headerlink" title="Web API"></a>Web API</h1><p>Web API是浏览器提供的一套操作浏览器功能和页面元素的API（DOM和BOM）</p>
<h1 id="DOM"><a href="#DOM" class="headerlink" title="DOM"></a>DOM</h1><p>可以改变网页的内容、结构和样式</p>
<h2 id="DOM树"><a href="#DOM树" class="headerlink" title="DOM树"></a>DOM树</h2><p><img src="http://helloxx.cn/DOM%E6%A0%91.png" srcset="/myblog/img/loading.gif" alt="DOM树"></p>
<p>文档：一个页面就是一个文档  document<br>元素：页面中的所有标签都是元素，element<br>节点：网页中的所有内容都是节点（标签、属性、文本、注释等），node</p>
<p><strong>DOM把以上内容都看作是对象</strong></p>
<h1 id="DOM操作"><a href="#DOM操作" class="headerlink" title="DOM操作"></a>DOM操作</h1><h2 id="获取元素"><a href="#获取元素" class="headerlink" title="获取元素"></a>获取元素</h2><h3 id="getElementById"><a href="#getElementById" class="headerlink" title="getElementById()"></a>getElementById()</h3><p>注意：</p>
<ul>
<li>因为文档页面从上往下加载，所以先有标签，然后才能getElementById</li>
<li>参数是字符串，所以需要加引号</li>
<li>返回的是一个 element 对象</li>
</ul>
<p>console.dir 可以打印返回的元素对象，更好的查看里面的属性和方法</p>
<h3 id="getElementsByTagName"><a href="#getElementsByTagName" class="headerlink" title="getElementsByTagName()"></a>getElementsByTagName()</h3><ul>
<li>参数是字符串，所以需要加引号d</li>
<li>得到的是对象的集合，可以用遍历来获取所有对象</li>
<li>得到的是动态的<br>例子: 获取ol里面的li</li>
</ul>
<pre><code class="html">&lt;ol&gt;
&lt;li&gt;123一二三四五&lt;/li&gt;
&lt;li&gt;123上山打老虎&lt;/li&gt;
&lt;li&gt;123老虎有几只&lt;/li&gt;
&lt;li&gt;123快来数一数&lt;/li&gt;
&lt;li&gt;123一二三四五&lt;/li&gt;
&lt;/ol&gt;
&lt;script&gt;
var ol = document.getElementsByTagName(&#39;ol&#39;);
//伪数组不能做父元素
var list = ol[0].getElementsByTagName(&#39;li&#39;);
console.log(list);
console.dir(list);</code></pre>
<h3 id="getElementsByClassName"><a href="#getElementsByClassName" class="headerlink" title="getElementsByClassName()"></a>getElementsByClassName()</h3><p>类名选择器</p>
<h3 id="querySelector"><a href="#querySelector" class="headerlink" title="querySelector()"></a>querySelector()</h3><p>HTML5新增的</p>
<p>返回指定选择器的<strong>第一个对象</strong></p>
<pre><code class="html">&lt;div class=&quot;box&quot;&gt;
&lt;ul&gt;
&lt;li&gt;15212&lt;/li&gt;
&lt;li&gt;1641238&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&quot;box&quot;&gt;
&lt;ul&gt;
&lt;li&gt;151232&lt;/li&gt;
&lt;li&gt;1612348&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;script&gt;
//注意这里括号里面必须有“.”，因为需要指定选择的选择器
var boxs = document.querySelector(&#39;.box&#39;);
console.log(boxs);
&lt;/script&gt;</code></pre>
<h3 id="querySelectorAll"><a href="#querySelectorAll" class="headerlink" title="querySelectorAll()"></a>querySelectorAll()</h3><p>返回指定选择器的所有对象集合<br>用法和querySelector()一样</p>
<h3 id="document-body"><a href="#document-body" class="headerlink" title="document.body"></a>document.body</h3><p>获取body元素</p>
<h3 id="document-documentElement"><a href="#document-documentElement" class="headerlink" title="document.documentElement"></a>document.documentElement</h3><p>获取html元素</p>
<h2 id="事件基础"><a href="#事件基础" class="headerlink" title="事件基础"></a>事件基础</h2><p>JavaScript使我们有能力创建动态页面，而事件是可以被JavaScript侦测到的行为。<br>网页中的每个元素都可以产生某些触发JavaScript的事件。</p>
<h3 id="事件由三部分组成："><a href="#事件由三部分组成：" class="headerlink" title="事件由三部分组成："></a>事件由三部分组成：</h3><ul>
<li>事件源   事件被触发的对象 比如按钮</li>
<li>事件类型   如何触发 比如鼠标点击、鼠标经过、键盘按下、滚动滚轮</li>
<li>事件处理程序   通过函数赋值的方式完成</li>
</ul>
<pre><code class="html">&lt;button id=&quot;btn&quot;&gt;按钮&lt;/button&gt;
&lt;script&gt;
    var btn = document.getElementById(&#39;btn&#39;);
    btn.onclick = function () {
        alert(&#39;触发事件&#39;);
    }
&lt;/script&gt;</code></pre>
<p>事件都有：</p>
<table>
<thead>
<tr>
<th>鼠标事件</th>
<th>触发条件</th>
</tr>
</thead>
<tbody><tr>
<td>onclick</td>
<td>鼠标点击左键触发</td>
</tr>
<tr>
<td>onmouseover</td>
<td>鼠标经过触发</td>
</tr>
<tr>
<td>onmouseout</td>
<td>鼠标离开触发</td>
</tr>
<tr>
<td>onfocus</td>
<td>获得鼠标焦点触发</td>
</tr>
<tr>
<td>onblur</td>
<td>失去鼠标焦点触发</td>
</tr>
<tr>
<td>onmousemove</td>
<td>鼠标移动触发</td>
</tr>
<tr>
<td>onmouseup</td>
<td>鼠标弹起触发</td>
</tr>
<tr>
<td>onmousedown</td>
<td>鼠标按下触发</td>
</tr>
</tbody></table>
<h2 id="操作元素"><a href="#操作元素" class="headerlink" title="操作元素"></a>操作元素</h2><p>JavaScript可以改变网页内容、结构和样式，我们可以利用DOM操作元素来改变元素里面的内容、属性等。</p>
<h3 id="element-innerText"><a href="#element-innerText" class="headerlink" title="element.innerText"></a>element.innerText</h3><ul>
<li>从起始位置到终止位置的内容，但它去除Html标签，同时空格和换行也会去掉</li>
<li>innerText不识别HTML标签</li>
<li>可读写的，可以获取元素里面的内容</li>
</ul>
<h3 id="element-innerHTML"><a href="#element-innerHTML" class="headerlink" title="element.innerHTML"></a>element.innerHTML</h3><ul>
<li>从起始位置到终止位置的全部内容，包括Html标签，同时保留空格和换行</li>
<li>能识别HTML标签</li>
<li>可读写的，可以获取元素里面的内容</li>
</ul>
<h3 id="修改表单属性"><a href="#修改表单属性" class="headerlink" title="修改表单属性"></a>修改表单属性</h3><p>disabled     让某个表单被禁用，不能被点击，<br>用法：</p>
<pre><code class="javascript">btn.onclick = function () {
    btn.disabled = true;
    //或者写成下面这种
    this.disabled = true;
    //this指向的是时间函数的调用者
}</code></pre>
<p><strong>案例</strong>：仿京东显示密码，点击按钮将密码框显示为文本框，并可以查看密码明文</p>
<p>算法：利用一个flag变量，如果是1就切换为文本框，如果是0就切换为密码框</p>
<pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;style&gt;
    * {
        margin: 0;
        padding: 0;
    }
    form {
        position: relative;
        width: 1000px;
        height: 500px;
        border: 1px solid red;
        margin: 100px auto 0;
    }
    input {
        display: block;
        width: 800px;
        height: 50px;
        line-height: 30px;
        color: #3c3c3c;
        margin: 50px auto 50px;
        padding-left: 20px;
        box-sizing: border-box;
        border: 1px solid red;
    }
    label img {
        top: 164px;
        right: 120px;
        position: absolute;
        width: 24px;
    }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form action=&quot;#&quot;&gt;
        &lt;input type=&quot;text&quot; id=&quot;userName&quot; placeholder=&quot;请输入你的用户名&quot;&gt;
        &lt;label for=&quot;&quot;&gt;
            &lt;img src=&quot;images/闭眼.png&quot; alt=&quot;&quot;&gt;
        &lt;/label&gt;
        &lt;input type=&quot;password&quot; id=&quot;password&quot; placeholder=&quot;请输入你的密码&quot;&gt;
    &lt;/form&gt;
    &lt;script&gt;
    var eye = document.querySelector(&#39;img&#39;);
    var password = document.getElementById(&#39;password&#39;);
    var flag = 0;
    eye.onclick = function () {
        if (flag === 0) {
            password.type = &#39;text&#39;;
            eye.src = &#39;images/睁眼.png&#39;;
            flag = 1;
        } else {
            password.type = &#39;password&#39;;
            eye.src = &#39;images/闭眼.png&#39;;
            flag = 0;
        }

    }
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h3 id="修改样式属性"><a href="#修改样式属性" class="headerlink" title="修改样式属性"></a>修改样式属性</h3><h4 id="element-style"><a href="#element-style" class="headerlink" title="element.style"></a>element.style</h4><p>行内样式操作，修改元素样式，如果样式比较少或者功能简单的情况下使用<br>注意：</p>
<ul>
<li>里面的属性是驼峰命名法</li>
<li>JS修改的是行内样式，权重比CSS的高<h4 id="element-className"><a href="#element-className" class="headerlink" title="element.className"></a>element.className</h4></li>
</ul>
<p>类名样式操作，适合样式比较多的情况下使用<br>修改了元素的类名</p>
<p><strong>注意：</strong>这个方法直接修改了类名，也就是说会覆盖原来的类名，原来的就不生效了<br>如果想要保留原先的类名，这样做：</p>
<pre><code class="js">//假设first 是原来的类名，change是想加入的
this.className = &#39;first change&#39;;</code></pre>
<h4 id="表单事件"><a href="#表单事件" class="headerlink" title="表单事件"></a>表单事件</h4><p>获得焦点 onfocus<br>失去焦点 onblur</p>
<p>案例：京东搜索框，默认是“手机”两个字，当用户点击搜索框的时候，“手机”两个字消失，当输入文本之后，保持文本内容不变</p>
<p>分析：</p>
<ul>
<li>如果获得焦点，判断里面是否是默认文字，如果是默认文字，就清空表单内容</li>
<li>如果失去焦点，判断表单是否为空，如果为空，则表单内容改为默认文字</li>
<li>获得焦点的时候，把文本框里的文字变黑</li>
<li>失去焦点的时候，文本框文字变浅</li>
</ul>
<pre><code class="html">&lt;input type=&quot;text&quot; value=&quot;手机&quot;&gt;
&lt;script&gt;
    var input = document.querySelector(&#39;input&#39;);
    input.onfocus = function () {
        if (this.value === &#39;手机&#39;) {
            input.value = &#39;&#39;;
        }
        this.style.color = &#39;#3c3c3c&#39;; 
    }
    input.onblur = function () {
        if (this.value === &#39;&#39;) {
            input.value = &#39;手机&#39;;
        }
        this.style.color = &#39;#999&#39;;
    }
&lt;/script&gt;</code></pre>
<p>案例：密码提示框，选中的时候提示密码的长度和标准，失去焦点的时候，检查密码是否合乎规范</p>
<p>分析：</p>
<ul>
<li>如果获得焦点，提示密码的长度和标准</li>
<li>如果失去焦点，检查密码是否合乎规范，如果不符合规范，就提示</li>
<li>因为改变的样式比较多，所以用className来修改样式</li>
</ul>
<pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;style&gt;
    div {
        width: 600px;
        margin: 100px auto;
    }
    .message {
        display: inline-block;
        font-size: 12px;
        color: #999;
        background: url(images/message.png) no-repeat left center;
        background-size: 16px;
        padding-left: 20px;
    }
    .error {
        display: inline-block;
        font-size: 12px;
        color: red;
        background: url(images/error.png) no-repeat left center;
        background-size: 16px;
        padding-left: 20px;
    }
    .right {
        display: inline-block;
        font-size: 12px;
        color: green;
        background: url(images/right.png) no-repeat left center;
        background-size: 16px;
        padding-left: 20px;
    }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&quot;register&quot;&gt;
        &lt;input type=&quot;password&quot; class=&quot;pwd&quot;&gt;
        &lt;p class=&quot;message&quot;&gt;请输入6~16位密码&lt;/p&gt;
    &lt;/div&gt;
    &lt;script&gt;
    var pwd = document.querySelector(&#39;.pwd&#39;);
    var message = document.querySelector(&#39;.message&#39;);
    pwd.onblur = function() {
        if (pwd.value.length &gt; 16 || pwd.value.length &lt; 6) {

            message.className = &#39;error&#39;;
            message.innerHTML = &#39;您输入的位数不对，要求6~16位&#39;;
        } else {
            message.className = &#39;right&#39;;
            message.innerHTML = &#39;对辽~&#39;;
        }
    }
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h3 id="操作元素小总结"><a href="#操作元素小总结" class="headerlink" title="操作元素小总结"></a>操作元素小总结</h3><pre><code class="mermaid">graph LR
A[操作元素]  --&gt;B[操作元素内容]
B  --&gt;F[innerText]
B  --&gt;G[innerHTML]
A[操作元素]  --&gt;C[操作常见元素属性]
C --&gt;H[src href title alt等 ]
A[操作元素]  --&gt;D[操作表单元素属性]
D --&gt;I[ type value disabled等]
A[操作元素]  --&gt;E[操作元素样式属性]
E --&gt;J[element.style]
E --&gt;K[element.className]</code></pre>
<h3 id="排他思想"><a href="#排他思想" class="headerlink" title="排他思想"></a>排他思想</h3><p>两层循环，先排除其他人，然后再设置自己的样式</p>
<pre><code class="html">    &lt;button&gt;按钮1&lt;/button&gt;
    &lt;button&gt;按钮2&lt;/button&gt;
    &lt;button&gt;按钮3&lt;/button&gt;
    &lt;button&gt;按钮4&lt;/button&gt;
    &lt;button&gt;按钮5&lt;/button&gt;
    &lt;script&gt;
    var btns = document.querySelectorAll(&#39;button&#39;);
    for (var i = 0; i &lt; btns.length; i++) {
        btns[i].onclick = function () {
            //  1. 先把所有颜色的背景颜色都清空
            for (var j = 0; j &lt; btns.length; j++) {
                btns[j].style.backgroundColor = &#39;&#39;;
            }
            //  2. 再把想要的背景颜色改成pink
            this.style.backgroundColor = &#39;pink&#39;;
        }
    }
    &lt;/script&gt;</code></pre>
<p>案例：百度换肤效果</p>
<p>分析：</p>
<ul>
<li>利用循环给一组元素注册点击事件</li>
<li>当鼠标经过一张图片，当前的页面背景换成经过的图片，鼠标移开之后，换回默认的</li>
<li>当点击了图片，当前的页面背景换成点击的图片</li>
<li>核心算法：把当前图片的src路径取过来，给body作为背景</li>
</ul>
<pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;

&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;style&gt;
        * {
            margin: 0;
            padding: 0;
        }

        body {
            background: url(images/bg1.jpg) no-repeat center top;
        }

        li {
            list-style: none;
        }

        .baidu {
            overflow: hidden;
            margin: 100px auto;
            background-color: #fff;
            width: 410px;
            padding-top: 3px;
        }

        .baidu li {
            float: left;
            margin: 0 1px;
            cursor: pointer;
        }

        .baidu img {
            width: 100px;
        }
    &lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

    &lt;ul class=&quot;baidu&quot;&gt;
        &lt;li&gt;&lt;img src=&quot;images/bg1.jpg&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
        &lt;li&gt;&lt;img src=&quot;images/bg2.jpg&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
        &lt;li&gt;&lt;img src=&quot;images/bg3.jpg&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
        &lt;li&gt;&lt;img src=&quot;images/bg4.jpg&quot; alt=&quot;&quot;&gt;&lt;/li&gt;
    &lt;/ul&gt;
    &lt;script&gt;
        //获取元素
        var images = document.querySelector(&#39;.baidu&#39;).querySelectorAll(&#39;img&#39;);
        for (var i = 0; i &lt; images.length; i++) {
            //temp 存储原来的背景
            var temp;
            images[i].onclick = function () {
                document.body.style.backgroundImage = &#39;url(&#39; + this.src + &#39;)&#39;;
                temp = &#39;url(&#39; + this.src + &#39;)&#39;;
            }
            images[i].onmouseover = function () {
                temp = document.body.style.backgroundImage;
                document.body.style.backgroundImage = &#39;url(&#39; + this.src + &#39;)&#39;;
            }
            images[i].onmouseout = function () {
                document.body.style.backgroundImage = temp;
            }
        }
    &lt;/script&gt;
&lt;/body&gt;

&lt;/html&gt;</code></pre>
<p>案例： 表单全选取消全选</p>
<p>分析：</p>
<ul>
<li>点击上面全选复选框，下面所有的复选框都选中（全选）</li>
<li>再次点击全选复选框，下面所有的复选框都不中选（取消全选）</li>
<li>如果下面复选框全部选中，上面全选按钮就自动选中</li>
<li>如果下面复选框有一个没有选中，上面全选按钮就不选中</li>
<li>所有复选框一开始默认都没选中状态</li>
<li>下面复选框需要全部选中，上面全选才能选中做法：给下面所有复选框绑定点击事件，每次点击，都要循环查看下面所有的复选框是否有没选中的，如果有一个没选中的上面全选就不选中。</li>
</ul>
<pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;style&gt;
        table {
            width: 800px;
            height: 500px;
            margin: 0 auto;
            border: 1px solid #999;
            text-align: center;
        }
        table tbody tr {
            background-color: rgb(163, 163, 163);
        }
        thead {
            background-color: skyblue;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;table&gt;
        &lt;thead&gt;
            &lt;tr&gt;
                &lt;th&gt;&lt;input type=&quot;checkbox&quot; name=&quot;&quot; id=&quot;checkAll&quot; &gt;&lt;/th&gt;
                &lt;th&gt;商品&lt;/th&gt;
                &lt;th&gt;价格&lt;/th&gt;
            &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;&quot; id=&quot;&quot;&gt;&lt;/td&gt;
                &lt;td&gt;iPhone Xs Max&lt;/td&gt;
                &lt;td&gt;10000&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;&quot; id=&quot;&quot;&gt;&lt;/td&gt;
                &lt;td&gt;iPad Pro&lt;/td&gt;
                &lt;td&gt;5000&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;&quot; id=&quot;&quot;&gt;&lt;/td&gt;
                &lt;td&gt;iWatch&lt;/td&gt;
                &lt;td&gt;3000&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;&lt;input type=&quot;checkbox&quot; name=&quot;&quot; id=&quot;&quot;&gt;&lt;/td&gt;
                &lt;td&gt;AirPods&lt;/td&gt;
                &lt;td&gt;1000&lt;/td&gt;         
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
    &lt;script&gt;
        var checkAll = document.querySelector(&#39;#checkAll&#39;);
        var trs = document.querySelector(&#39;tbody&#39;).querySelectorAll(&#39;tr&#39;);
        var tbCheck = document.querySelector(&#39;tbody&#39;).getElementsByTagName(&#39;input&#39;);
        for (var i = 0; i &lt; trs.length; i++) {
            trs[i].onmouseover = function () {
                this.style.backgroundColor = &#39;rgb(200, 200, 200)&#39;;
            }
            trs[i].onmouseout = function () {
                this.style.backgroundColor = &#39;&#39;;
            }
        }
        checkAll.onclick = function () {
            for (var j = 0; j &lt; tbCheck.length; j++) {
                tbCheck[j].checked = checkAll.checked;
            }
        }
        //下面的全部选中，上面的就选中
        for (var i = 0; i &lt; tbCheck.length; i++) {
            tbCheck[i].onclick = function () {
                // flag 控制全选按钮是否被选中
                var flag = true;
                for (var j = 0; j &lt; tbCheck.length; j++) {
                    if (!(tbCheck[j].checked)) {
                        flag = false;
                        break;      // 退出for循环，提高运行效率
                    }
                }
                checkAll.checked = flag;
            }
        }
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h3 id="操作元素-1"><a href="#操作元素-1" class="headerlink" title="操作元素"></a>操作元素</h3><h4 id="获取属性值"><a href="#获取属性值" class="headerlink" title="获取属性值"></a>获取属性值</h4><ul>
<li>element.属性     获取内置属性值（元素自带的属性）</li>
<li>element.getAttribute(‘属性’)    主要获取自定义的属性（标准），我们定义的属性</li>
</ul>
<h4 id="设置属性值"><a href="#设置属性值" class="headerlink" title="设置属性值"></a>设置属性值</h4><ul>
<li>element.属性 = ‘值’；</li>
<li>element.setAttribute(‘属性’, ‘值’)    主要更改自定义的属性</li>
</ul>
<h4 id="移除属性值"><a href="#移除属性值" class="headerlink" title="移除属性值"></a>移除属性值</h4><ul>
<li>element.removeAttribute(‘属性’)    主要移除自定义的属性（标准）</li>
</ul>
<h4 id="TAB案例-（重点）"><a href="#TAB案例-（重点）" class="headerlink" title="TAB案例 （重点）"></a>TAB案例 （重点）</h4><p>分析：</p>
<ul>
<li>一个大盒子，里面上下两个小盒子</li>
<li>上面的模块，点击某一个之后，这个的背景色是红色，其余的是灰色（排他思想）</li>
<li>点击某一个之后，显示这个模块对应的内容，其他的隐藏，这个要写到点击事件里面</li>
<li>下面的显示内容和上面的小 li 一一对应</li>
<li>核心思路：<ul>
<li>给上面的tab_list 添加自定义属性，属性号从0开始</li>
<li>当点击上面的模块，下面的队形的显示模块开始显示，其他的隐藏</li>
</ul>
</li>
</ul>
<pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;style&gt;
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            list-style: none;
        }
        .tab {
            width: 800px;
            height: 500px;
            margin: 200px auto;
        }
        .tab_list {
            height: 50px;
            background-color: rgb(162, 162, 162);
            border-bottom: 2px solid #c81623;
        }
        .tab_list ul li {
            float: left;
            display: inline-block;
            width: 150px;
            height: 50px;
            line-height: 50px;
            text-align: center;
            cursor: pointer;
        }
        .tab_list .current {
            background-color: #c81623;
            color: #fff;
        }
        .item {
            display: none;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&quot;tab&quot;&gt;
        &lt;div class=&quot;tab_list&quot;&gt;
            &lt;ul&gt;
                &lt;li class=&quot;current&quot;&gt;商品介绍&lt;/li&gt;
                &lt;li&gt;规格与包装&lt;/li&gt;
                &lt;li&gt;售后保障&lt;/li&gt;
                &lt;li&gt;商品评价(1.1万+)&lt;/li&gt;
                &lt;li&gt;手机社区&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;
        &lt;div class=&quot;tab_con&quot;&gt;
            &lt;div class=&quot;item&quot; style=&quot;display: block&quot;&gt;
                商品介绍模块内容
            &lt;/div&gt;
            &lt;div class=&quot;item&quot;&gt;
                规格与包装模块内容
            &lt;/div&gt;
            &lt;div class=&quot;item&quot;&gt;
                售后保障模块内容
            &lt;/div&gt;
            &lt;div class=&quot;item&quot;&gt;
                商品评价模块内容
            &lt;/div&gt;
            &lt;div class=&quot;item&quot;&gt;
                手机社区模块内容
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/div&gt;
    &lt;script&gt;
    var tab_list = document.querySelector(&#39;.tab_list&#39;);
    var lis = tab_list.querySelectorAll(&#39;li&#39;);
    var items = document.querySelectorAll(&#39;.item&#39;);
    for (var i = 0; i &lt; lis.length; i++) {
        //给5个li设置索引号
        lis[i].setAttribute(&#39;index&#39;, i);
        lis[i].onclick = function () {
            //干掉其他人
            for (var j = 0; j &lt; lis.length; j++) {
                lis[j].className = &#39;&#39;;
            }
            this.className = &#39;current&#39;;
            var index = this.getAttribute(&#39;index&#39;);
            for (var k = 0; k &lt; items.length; k++) {
                items[k].style.display = &#39;none&#39;;
            }
            items[index].style.display = &#39;block&#39;;
        }


    }
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h3 id="H5自定义属性"><a href="#H5自定义属性" class="headerlink" title="H5自定义属性"></a>H5自定义属性</h3><p>自定义属性目的：为了保存并使用数据，有些数据保存到页面中，为不是数据库中</p>
<h4 id="设置H5自定义属性"><a href="#设置H5自定义属性" class="headerlink" title="设置H5自定义属性"></a>设置H5自定义属性</h4><p>但是有些自定义属性容易引以歧义，不容易判断是内置属性还是自定义属性，所以H5给我们新增了自定义属性<br>H5规定自定义属性以 “data-”  开头</p>
<h4 id="获取H5自定义属性"><a href="#获取H5自定义属性" class="headerlink" title="获取H5自定义属性"></a>获取H5自定义属性</h4><ul>
<li>兼容性：element.getAttribute(‘属性’)</li>
<li>H5新增：element.dataset.index 或者 element.dataset[ ‘index’ ]</li>
</ul>
<p>注意：</p>
<pre><code class="html">&lt;div data-list-name=&quot;andy&quot;&gt;&lt;/div&gt;
&lt;script&gt;
var div = document.querySelector(&#39;div&#39;);
console.log(div.getAttribute(&#39;data-list-name&#39;));
//上下三种方法都可以，但是如果用下面这两种方法的话，要用驼峰命名法
console.log(div.dataset.listName);
console.log(div.dataset[&#39;listName&#39;]);
&lt;/script&gt;</code></pre>
<h2 id="节点操作"><a href="#节点操作" class="headerlink" title="节点操作"></a>节点操作</h2><p>利用DOM提供的方法获取元素  （逻辑性不强，繁琐）</p>
<ul>
<li>document.getElementById()</li>
<li>document.getElementByTagName()</li>
<li>document.querySelector  等等</li>
</ul>
<p>利用    （简单、符合逻辑）</p>
<ul>
<li>利用父子兄的节点关系获取元素</li>
<li>逻辑性强，但是兼容性差</li>
</ul>
<h3 id="节点"><a href="#节点" class="headerlink" title="节点"></a>节点</h3><p><img src="http://helloxx.cn/DOM%E6%A0%91.png" srcset="/myblog/img/loading.gif" alt="DOM树"></p>
<p>页面中所有的内容（标签、属性、文本、注释等）都是节点。节点用node表示。</p>
<p>HTML DOM树中的所有节点均可通过JavaScript 进行访问，所有HTML节点均可被修改，也可以创建或删除。</p>
<p>一般的，节点至少由nodeType（节点类型）、 nodeName（节点名称）、 nodeValue（节点值）这三个基本属性。</p>
<ul>
<li>元素节点 nodeType 为1</li>
<li>属性节点 nodeType 为2</li>
<li>文本节点 nodeType 为3 （文本节点包括文字、空格、换行等等）</li>
</ul>
<p>在实际开发中，节点操作主要操作的是元素节点。</p>
<h3 id="节点层级"><a href="#节点层级" class="headerlink" title="节点层级"></a>节点层级</h3><p>最常见的是<strong>父子兄层级关系</strong>。</p>
<h4 id="父级节点"><a href="#父级节点" class="headerlink" title="父级节点"></a>父级节点</h4><p>node.parentNode</p>
<p>注意：得到的离元素最近的父级节点（亲爸爸），如果找不到就返回null</p>
<h4 id="子级节点"><a href="#子级节点" class="headerlink" title="子级节点"></a>子级节点</h4><p>parentNode.childNodes     (标准)</p>
<p>返回包含指定节点的子节点的集合，该集合为即时更新的集合<br>包含的子节点包含元素节点、文本节点等等</p>
<p>所以用 nodeType 判断，用for循环遍历</p>
<p>parentNode.children     (非标准)</p>
<p>得到所有的子元素节点，虽然是非标准的，但是得到了浏览器的支持，所以以后大量使用这个</p>
<p>parentNode.firstChild</p>
<p>返回第一个子节点，找不到返回null,不管是文本节点还是元素节点都能找到</p>
<p>parentNode.firstElementChild</p>
<p>返回第一个子元素节点，找不到返回null,只返回元素节点（IE9以上才支持）</p>
<p>parentNode.lastChild</p>
<p>返回最后一个子节点，找不到返回null,不管是文本节点还是元素节点都能找到</p>
<p>parentNode.lastElementChild</p>
<p>返回最后一个子元素节点，找不到返回null,只返回元素节点（IE9以上才支持）</p>
<p>实际开发中的办法：</p>
<p>parentNode.children[i]</p>
<h4 id="案例"><a href="#案例" class="headerlink" title="案例"></a>案例</h4><p>案例：新浪下拉菜单</p>
<p>分析：nav导航栏中有ul和li，li下面又有ul和li，第二层ul和li在鼠标移上去的时候才显示</p>
<ul>
<li>导航栏里面的li都要有鼠标经过的效果，所以需要循环注册</li>
<li>核心原理：当鼠标经过li 的时候，孩子的ul 和li 显示，当鼠标离开，则隐藏</li>
</ul>
<pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta http-equiv=&quot;X-UA-Compatible&quot; content=&quot;ie=edge&quot;&gt;
    &lt;title&gt;新浪网&lt;/title&gt;
    &lt;style&gt;
        * {
            margin: 0;
            padding: 0;
        }
        ul {
            list-style: none;
        }
        a {
            text-decoration: none; 
        }
        .nav {
            width: 800px;
            margin: 200px auto;
            position: relative;
        }
        .nav&gt;li {
            width: 80px;
            height: 100%;
            line-height: 41px;
            color: #333;
            float: left;
            position: relative;
            text-align: center;
        }
        .nav&gt;li&gt;a:hover {
            background-color: #eee;
        }

        .nav li ul {
            display: none;
            position: absolute;
            top: 41px;
            left: 0;
            width: 100%;
            border-left: 1px solid #fecc5b;
            border-right: 1px solid #fecc5b;
            box-sizing: border-box;
        }
        .nav li ul li {
            border-bottom: 1px solid #fecc5b;
/*             width: 50px;
            text-align: center; */

        }
        .nav ul li a:hover {
            background-color: #FFF5DA;
        } 
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;ul class=&quot;nav&quot;&gt;
        &lt;li&gt;
            &lt;a href=&quot;#&quot;&gt;微博&lt;/a&gt;
            &lt;ul&gt;
                &lt;li&gt;
                    &lt;a href=&quot;#&quot;&gt;私信&lt;/a&gt;
                &lt;/li&gt;
                &lt;li&gt;
                    &lt;a href=&quot;#&quot;&gt;评论&lt;/a&gt;
                &lt;/li&gt;
                &lt;li&gt;
                    &lt;a href=&quot;#&quot;&gt;@我&lt;/a&gt;
                &lt;/li&gt;
            &lt;/ul&gt;
        &lt;/li&gt;
        &lt;li&gt;
            &lt;a href=&quot;#&quot;&gt;微博&lt;/a&gt;
            &lt;ul&gt;
                &lt;li&gt;
                    &lt;a href=&quot;#&quot;&gt;私信&lt;/a&gt;
                &lt;/li&gt;
                &lt;li&gt;
                    &lt;a href=&quot;#&quot;&gt;评论&lt;/a&gt;
                &lt;/li&gt;
                &lt;li&gt;
                    &lt;a href=&quot;#&quot;&gt;@我&lt;/a&gt;
                &lt;/li&gt;
            &lt;/ul&gt;
        &lt;/li&gt;
        &lt;li&gt;
            &lt;a href=&quot;#&quot;&gt;微博&lt;/a&gt;
            &lt;ul&gt;
                &lt;li&gt;
                    &lt;a href=&quot;#&quot;&gt;私信&lt;/a&gt;
                &lt;/li&gt;
                &lt;li&gt;
                    &lt;a href=&quot;#&quot;&gt;评论&lt;/a&gt;
                &lt;/li&gt;
                &lt;li&gt;
                    &lt;a href=&quot;#&quot;&gt;@我&lt;/a&gt;
                &lt;/li&gt;
            &lt;/ul&gt;
        &lt;/li&gt;

    &lt;/ul&gt;
    &lt;script&gt;
    //获取元素
    var nav = document.querySelector(&#39;.nav&#39;);
    var lis = nav.children;
    //循环注册事件
    for (var i = 0; i &lt; lis.length; i++) {
        lis[i].onmouseover = function () {
            this.children[1].style.display = &#39;block&#39;;
        }
        lis[i].onmouseout = function () {
            this.children[1].style.display = &#39;none&#39;;
        }
    }
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h4 id="兄弟节点"><a href="#兄弟节点" class="headerlink" title="兄弟节点"></a>兄弟节点</h4><p>node.nextSibling 得到下一个兄弟节点，包括元素节点和文本节点<br>node.previousSibling  得到上一个兄弟节点，包括元素节点和文本节点</p>
<p>下面两个方法只有IE9以上才能兼容<br>node.nextElementSibling 得到下一个兄弟元素节点，只有元素节点<br>node.previousElementSibling  得到上一个兄弟元素节点，只有元素节点</p>
<h4 id="创建节点"><a href="#创建节点" class="headerlink" title="创建节点"></a>创建节点</h4><p>document.createElement(‘tagName’)</p>
<p>这个方法创建由tagName指定的 HTML 元素，因为这些元素原先不存在，是根据我们的需求动态生成的，所以也称为<strong>动态创建元素节点</strong>。</p>
<p>node.appendChild(child);</p>
<p>它是追加元素，是在指定父节点的子节点的末尾添加。</p>
<p>node.insertBefore(child, 指定元素);</p>
<h4 id="留言板案例"><a href="#留言板案例" class="headerlink" title="留言板案例"></a>留言板案例</h4><p>分析：</p>
<ul>
<li>页面组成：一个文本域，一个提交按钮，一个留言板</li>
<li>当点击提交按钮的时候，先判断文本域内容是不是空，如果是空，就警告</li>
<li>如果不是空，就新建一个li，然后把文本域的内容赋值给li，然后在ul里面的前面添加li</li>
</ul>
<h4 id="删除节点"><a href="#删除节点" class="headerlink" title="删除节点"></a>删除节点</h4><p>node.removeChild(child);</p>
<p>从DOM中删除一个子节点，返回删除的节点</p>
<h4 id="删除留言案例"><a href="#删除留言案例" class="headerlink" title="删除留言案例"></a>删除留言案例</h4><p>案例分析：</p>
<ul>
<li>在留言板案例的基础上添加功能</li>
<li>当把文本域的内容幅值给 li 的时候，多添加一个删除的链接，</li>
<li>循环把所有的链接获取过来，当我们点击一个链接的时候，删除当前链接所在的 li</li>
<li>阻止链接跳转需要添加javascript:void(0);或者 javascript:;</li>
</ul>
<pre><code class="javascript">&lt;script&gt;
        //获取元素
        var btn = document.querySelector(&#39;button&#39;);
        var text = document.querySelector(&#39;textarea&#39;);
        var ul = document.querySelector(&#39;ul&#39;);
        //注册事件
        btn.onclick = function () {
            if (text.value == &#39;&#39;) {
                alert(&#39;您没有输入任何内容&#39;);
                return false;
            } else {
                var li = document.createElement(&#39;li&#39;);
                //将文本域的内容赋值给li，同时后面添加一个删除留言的a链接
                li.innerHTML = text.value + &quot;&lt;a href=&#39;javascript:;&#39;&gt;删除&lt;/a&gt;&quot;;
                ul.insertBefore(li, ul.children[0]);
                var as = document.querySelectorAll(&#39;a&#39;); 
                for (var i = 0; i &lt; as.length; i++) {
                    as[i].onclick = function () {
                        //删除的是a当前所在的li
                        ul.removeChild(this.parentNode);
                    }
                }               
            }
        }
    &lt;/script&gt;</code></pre>
<h4 id="复制节点（克隆节点）"><a href="#复制节点（克隆节点）" class="headerlink" title="复制节点（克隆节点）"></a>复制节点（克隆节点）</h4><p>node.cloneNode()<br>这个方法返回一个节点的副本</p>
<p>注意：</p>
<ul>
<li>如果括号里面的参数为空，那么只是浅拷贝，即只复制节点本身，不克隆里面的子节点</li>
<li>如果括号里面的参数为true，那么是深拷贝，复制标签并且复制里面的内容</li>
</ul>
<h4 id="三种动态创建元素区别"><a href="#三种动态创建元素区别" class="headerlink" title="三种动态创建元素区别"></a>三种动态创建元素区别</h4><ul>
<li>document.write()<ul>
<li>文档流执行完毕之后，他会导致页面全部重绘</li>
</ul>
</li>
<li>document.innerHTML()<ul>
<li>将内容写入某个DOM节点，不会导致页面全部重绘</li>
<li>拼接字符串的效率低</li>
<li>创建多个元素效率更高，（不要拼接字符串，采取数组形式拼接），结构稍显复杂</li>
</ul>
</li>
<li>document.createElement()<ul>
<li>创建多个元素效率稍低一点点，但是结构更清晰</li>
</ul>
</li>
</ul>
<p><strong>总结</strong>：不同浏览器下，innerHTML比createElement效率高</p>
<h2 id="DOM重点核心"><a href="#DOM重点核心" class="headerlink" title="DOM重点核心"></a>DOM重点核心</h2><p>文档对象模型</p>
<h3 id="增"><a href="#增" class="headerlink" title="增"></a>增</h3><ul>
<li>appendChild</li>
<li>insertBefore</li>
</ul>
<h3 id="删"><a href="#删" class="headerlink" title="删"></a>删</h3><ul>
<li>removeChild</li>
</ul>
<h3 id="改"><a href="#改" class="headerlink" title="改"></a>改</h3><p>修改DOM元素的属性，DOM元素的内容、属性、表单的值等</p>
<ul>
<li>修改元素属性：src、href、title等</li>
<li>修改普通元素内容：innerHTML、innerText</li>
<li>修改表单元素：value、type、disable等</li>
<li>修改元素样式：style、className</li>
</ul>
<h3 id="查"><a href="#查" class="headerlink" title="查"></a>查</h3><ul>
<li>DOM提供的API方法：getElementById、getElementByTagName古老用法不太推荐</li>
<li>H5提供的新方法：querySelecter、querySelectorAll提倡使用</li>
<li>利用节点操作获取元素：父（parentNode）、子（children）、兄（previousElementSibling、nextElementSibling）提倡使用</li>
</ul>
<h3 id="属性操作"><a href="#属性操作" class="headerlink" title="属性操作"></a>属性操作</h3><ul>
<li>setAttribute ： 设置DOM的属性</li>
<li>getAttribute ： 得到DOM的属性</li>
<li>removeAttribute ： 移除属性</li>
</ul>
<h3 id="事件操作"><a href="#事件操作" class="headerlink" title="事件操作"></a>事件操作</h3><table>
<thead>
<tr>
<th>鼠标事件</th>
<th>触发条件</th>
</tr>
</thead>
<tbody><tr>
<td>onclick</td>
<td>鼠标点击左键触发</td>
</tr>
<tr>
<td>onmouseover</td>
<td>鼠标经过触发</td>
</tr>
<tr>
<td>onmouseout</td>
<td>鼠标离开触发</td>
</tr>
<tr>
<td>onfocus</td>
<td>获得鼠标焦点触发</td>
</tr>
<tr>
<td>onblur</td>
<td>失去鼠标焦点触发</td>
</tr>
<tr>
<td>onmousemove</td>
<td>鼠标移动触发</td>
</tr>
<tr>
<td>onmouseup</td>
<td>鼠标弹起触发</td>
</tr>
<tr>
<td>onmousedown</td>
<td>鼠标按下触发</td>
</tr>
</tbody></table>
<h2 id="事件高级"><a href="#事件高级" class="headerlink" title="事件高级"></a>事件高级</h2><h3 id="注册事件"><a href="#注册事件" class="headerlink" title="注册事件"></a>注册事件</h3><p>给元素添加事件，称为注册时间或者绑定事件。</p>
<p>注册事件有两种方式：传统方式和方法监听注册方式</p>
<h3 id="传统注册方式"><a href="#传统注册方式" class="headerlink" title="传统注册方式"></a>传统注册方式</h3><ul>
<li>利用on开头的事件onclick</li>
<li><code>&lt;button onclick=&quot;alert(&#39;hi&#39;)&quot;&gt;&lt;/button&gt;</code></li>
<li>btn.onclick = function () {}</li>
<li>特点：注册事件的<strong>唯一性</strong></li>
<li>同一个元素同一个事件著能设置一个处理函数，最后注册的处理函数将会覆盖前面注册的处理函数</li>
</ul>
<h3 id="监听注册方式"><a href="#监听注册方式" class="headerlink" title="监听注册方式"></a>监听注册方式</h3><ul>
<li>W3C标准推荐方式</li>
<li>addEventListener() 它是一个方法</li>
<li>IE9之前的IE浏览器不支持此方法，可使用attachEvent()代替</li>
<li>特点: 同一个元素同一个事件可以注册多个监听器</li>
</ul>
<h3 id="addEventListener-方法"><a href="#addEventListener-方法" class="headerlink" title="addEventListener() 方法"></a>addEventListener() 方法</h3><pre><code class="js">eventTarget.addEventListener(type, listener[, useCapture])</code></pre>
<p><code>eventTarget.addEventListener(type, listener[, useCapture])</code>方法将指定的监听器注册到eventTarget 上，当该对象触发指定的事件时，就会执行事件处理函数。</p>
<p>该方法接收三个参数：</p>
<ul>
<li>type : 事件类型字符串，比如click、mouseover，<strong>注意这里不要带on</strong>，是字符串，带引号</li>
<li>listener ： 事件处理函数，事件发生时，会调用该监听函数</li>
<li>useCapture : 可选函数，是一个布尔值，默认是false 。学完DOM事件流之后，再进一步学习</li>
</ul>
<h3 id="attachEvent"><a href="#attachEvent" class="headerlink" title="attachEvent"></a>attachEvent</h3><p><strong>该特性非标准，请尽量不要在生产环境中使用它</strong></p>
<pre><code>eventTarget.attackEvent(eventNameWithon, callback)</code></pre><p>eventTarget.attackEvent方法将指定的监听器注册到eventTarget 上，当该对象触发指定的事件时，指定的回调函数将会被执行。</p>
<p>该方法接收两个参数：</p>
<ul>
<li>ventNameWithon ： 事件类型字符串，比如onclick，onmouseover， 这里要带on</li>
<li>callback : 事件处理函数，当目标触发事件时回调函数将被调用</li>
</ul>
<h3 id="注册事件的兼容性解决方案"><a href="#注册事件的兼容性解决方案" class="headerlink" title="注册事件的兼容性解决方案"></a>注册事件的兼容性解决方案</h3><pre><code class="html">    &lt;button&gt;点击我&lt;/button&gt;
    &lt;script&gt;
        var btn = document.querySelector(&#39;button&#39;);
        function alertWarn () {
            alert (&#39;warning&#39;);
        }
        function addEventListener(element, eventName, fn) {
            //判断浏览器是否支持addEventListener方法
            if (element.addEventListener) {
                element.addEventListener (eventName, fn);   //第三个参数，默认是false
            } else if (element.attachEvent) {
                element.attachEvent (&#39;on&#39; + eventName, fn);
            } else {
                //相当于element.onclick = fn;
                element[&#39;on&#39; + eventName] = fn;
            }
        }
        addEventListener(btn, &#39;click&#39;, alertWarn);
    &lt;/script&gt;</code></pre>
<h2 id="删除事件"><a href="#删除事件" class="headerlink" title="删除事件"></a>删除事件</h2><h3 id="删除事件的方式"><a href="#删除事件的方式" class="headerlink" title="删除事件的方式"></a>删除事件的方式</h3><ul>
<li>传统注册方式<pre><code class="js">eventTarget.onclick = null;</code></pre>
</li>
<li>方法监听注册方式<pre><code class="js">divs[1].addEventListener(&#39;click&#39;, alertWarn);
function alertWarn () {
  alert(&#39;warning&#39;);
  divs[1].removeEventListener(&#39;click&#39;, alertWarn);
}</code></pre>
</li>
<li>attach 方式<pre><code class="js">divs[2].attachEvent(&#39;onclick&#39;, alertWarn1);
function alertWarn1 () {
  alert(&#39;warning&#39;);
  divs[1].detachEvent(&#39;click&#39;, alertWarn1);
}</code></pre>
</li>
<li>兼容性方案<br>参考上面的注册事件的兼容性方式。</li>
</ul>
<h2 id="DOM事件流"><a href="#DOM事件流" class="headerlink" title="DOM事件流"></a>DOM事件流</h2><p>事件流描述的是从页面中接收事件的顺序。</p>
<p>事件发生时会在元素节点之间按照特定的顺序传播，这个传播过程即DOM事件流。</p>
<p>包括三个阶段：</p>
<ol>
<li>事件捕获阶段</li>
<li>处于目标阶段</li>
<li>事件冒泡阶段</li>
</ol>
<p>注意:</p>
<ul>
<li>JS代码只能执行捕获或者冒泡其中的一个阶段</li>
<li>onclick 和 attachEvent 只能得到冒泡阶段</li>
<li>addEventListener (type, listener[, useCapture]) 第三个参数如果是true，表示在事件捕获阶段调用事件处理程序；如果是false（不写默认就是false），表示在事件冒泡阶段电泳事件处理程序。</li>
<li>在实际开发中，我们很少使用事件捕获，我们更关注事件冒泡</li>
<li>有些事件是没有冒泡的，比如onblur、onfocus、onmouseover、onmouseleave</li>
<li>虽然事件冒泡有时候会带来麻烦，但是有时候又会巧妙的做某些事情，我们后面讲解</li>
</ul>
<h2 id="事件对象"><a href="#事件对象" class="headerlink" title="事件对象"></a>事件对象</h2><ul>
<li>event 就是一个事件对象，写道我们的侦听函数的小括号里面，当形参来看</li>
<li>事件对象只有有了事件才会存在，他是系统给我们自动创建的，不需要我们传递参数</li>
<li>事件对象是我们的事件的一系列相关数据的集合，比如鼠标点击里面就包含了鼠标的相关信息</li>
<li>这个事件对象我们可以自己命名，比如 event、evt 、e 等</li>
<li>事件对象也有兼容性问题。 IE 6、7、8通过 window.event 实现</li>
</ul>
<p>兼容性写法：</p>
<pre><code>event = event || windoe.event;</code></pre><h3 id="事件对象常见的额属性和方法"><a href="#事件对象常见的额属性和方法" class="headerlink" title="事件对象常见的额属性和方法"></a>事件对象常见的额属性和方法</h3><table>
<thead>
<tr>
<th>事件对象属性方法</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>e.target</td>
<td>返回触发事件的对象  标准</td>
</tr>
<tr>
<td>e.scrElement</td>
<td>返回触发事件的对象  非标准 IE 6  7 8 使用</td>
</tr>
<tr>
<td>e.type</td>
<td>返回事件的类型，比如click、mouseover等，不带 on</td>
</tr>
<tr>
<td>e.cancelBubble</td>
<td>该属性阻止冒泡，非标准，IE 6 7 8 使用</td>
</tr>
<tr>
<td>e.returnValue</td>
<td>该属性阻止默认事件（默认行为）非标准 ，IE 6 7 8 使用，比如不让链接跳转</td>
</tr>
<tr>
<td>e.preventDefaule()</td>
<td>该方法阻止默认事件（默认行为）标准 ，比如不让链接跳转</td>
</tr>
<tr>
<td>e.stopPropagation()</td>
<td>阻止冒泡，标准</td>
</tr>
</tbody></table>
<h3 id="e-target-和-this-的区别"><a href="#e-target-和-this-的区别" class="headerlink" title="e.target 和 this 的区别"></a>e.target 和 this 的区别</h3><p>this 返回的是绑定事件的对象（元素）</p>
<p>e.target 返回的是点击的那个对象，就是谁触发了这个事件</p>
<pre><code>var ul = document.querySelector(&#39;ul&#39;);
ul.addEventListener(&#39;click&#39;, function (e) {
    console.log(this);
    console.log(e.target);
})

// &lt;ul&gt;...&lt;/ul&gt;
// &lt;li&gt;123&lt;/li&gt;</code></pre><h3 id="阻止对象默认行为"><a href="#阻止对象默认行为" class="headerlink" title="阻止对象默认行为"></a>阻止对象默认行为</h3><p>三种方法：</p>
<ul>
<li>e.preventDefaule();<br>是一个方法，适合普通浏览器</li>
<li>e.returnValue;</li>
<li>是一个属性，适用于 IE 6 7 8</li>
<li>return false;<br>没有兼容性问题，但是需要注意后面的语句就不执行了，直接跳出</li>
</ul>
<h3 id="阻止冒泡"><a href="#阻止冒泡" class="headerlink" title="阻止冒泡"></a>阻止冒泡</h3><ul>
<li>event.stopPropagation();    // 一般浏览器停止冒泡</li>
<li>event.cancelBubble;         // IE 6 7 8 的停止冒泡</li>
</ul>
<pre><code class="javascript">var father = document.querySelector(&#39;.father&#39;);
var son = document.querySelector(&#39;.son&#39;);
father.addEventListener(&#39;click&#39;, alertName, false);
son.addEventListener(&#39;click&#39;, alertName, false);
document.addEventListener(&#39;click&#39;,function () {
    alert(&#39;document&#39;);
}, false);
function alertName (event) {
    alert(this.getAttribute(&quot;class&quot;));
    event.stopPropagation();    // 停止冒泡
    event.cancelBubble;         // IE 6 7 8 的停止冒泡
}</code></pre>
<h2 id="事件委托（代理、委派）"><a href="#事件委托（代理、委派）" class="headerlink" title="事件委托（代理、委派）"></a>事件委托（代理、委派）</h2><h3 id="事件委托的原理"><a href="#事件委托的原理" class="headerlink" title="事件委托的原理"></a>事件委托的原理</h3><p>事件委托的原理：不给每个子节点单独设置事件监听器，而是设置在其父节点上，然后利用冒泡原理设置每个子节点。</p>
<p><strong>例如：</strong>给 ul 注册点击事件，然后利用事件对象的 target 来找到当前点击的 li ，然后事件冒泡到 ul 上， ul 有注册事件，就会触发事件监听器。</p>
<h3 id="事件委托的作用"><a href="#事件委托的作用" class="headerlink" title="事件委托的作用"></a>事件委托的作用</h3><p>只操作了一次 DOM ，提高了程序的性能。</p>
<h2 id="常用的鼠标事件"><a href="#常用的鼠标事件" class="headerlink" title="常用的鼠标事件"></a>常用的鼠标事件</h2><table>
<thead>
<tr>
<th>鼠标事件</th>
<th>触发条件</th>
</tr>
</thead>
<tbody><tr>
<td>onclick</td>
<td>鼠标点击左键触发</td>
</tr>
<tr>
<td>onmouseover</td>
<td>鼠标经过触发</td>
</tr>
<tr>
<td>onmouseout</td>
<td>鼠标离开触发</td>
</tr>
<tr>
<td>onfocus</td>
<td>获得鼠标焦点触发</td>
</tr>
<tr>
<td>onblur</td>
<td>失去鼠标焦点触发</td>
</tr>
<tr>
<td>onmousemove</td>
<td>鼠标移动触发</td>
</tr>
<tr>
<td>onmouseup</td>
<td>鼠标弹起触发</td>
</tr>
<tr>
<td>onmousedown</td>
<td>鼠标按下触发</td>
</tr>
</tbody></table>
<pre><code class="javascript">document.addEventListener(&#39;click&#39;, function (e) {
    console.log(e);
});</code></pre>
<table>
<thead>
<tr>
<th>鼠标事件对象</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>e.clientX</td>
<td>返回鼠标相对于浏览器窗口可视区域的X坐标</td>
</tr>
<tr>
<td>e.clientY</td>
<td>返回鼠标相对于浏览器窗口可视区域的Y坐标</td>
</tr>
<tr>
<td>e.pageX</td>
<td>返回鼠标相对于文档页面的X坐标 IE9+ 支持</td>
</tr>
<tr>
<td>e.pageY</td>
<td>返回鼠标相对于文档页面的Y坐标 IE9+ 支持</td>
</tr>
<tr>
<td>e.screenX</td>
<td>返回鼠标相对于电脑屏幕的X坐标</td>
</tr>
<tr>
<td>e.screenY</td>
<td>返回鼠标相对于电脑屏幕的Y坐标</td>
</tr>
</tbody></table>
<h3 id="案例-1"><a href="#案例-1" class="headerlink" title="案例:"></a>案例:</h3><p>跟随鼠标的小鸟:</p>
<h4 id="案例分析"><a href="#案例分析" class="headerlink" title="案例分析"></a>案例分析</h4><ul>
<li>鼠标不断的移动,使用鼠标移动事件: mousemove</li>
<li>在页面中移动,所以给 document 注册事件</li>
<li>图片要移动距离,而且不占位置,我们使用绝对定位即可</li>
<li>核心原理,每次鼠标移动,我们都会获得最新的鼠标坐标,把这个 X 和 Y 的坐标做为图片的 top 和 left 值就可以移动图片</li>
</ul>
<pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;

&lt;head&gt;
    &lt;title&gt;跟随鼠标的小鸟&lt;/title&gt;
    &lt;style&gt;
        img {
            position: absolute;
        }
    &lt;/style&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;img src=&quot;images/bird.gif&quot; alt=&quot;&quot;&gt;
    &lt;script&gt;
        var image = document.querySelector(&#39;img&#39;);
        document.addEventListener(&#39;mousemove&#39;, function (e) {
            // 只要鼠标移动，就会触发这个事件
            var x = e.pageX;
            var y = e.pageY;
            // top 和 left 一定要加 px
            image.style.left = x - 20 + &#39;px&#39;;
            image.style.top = y - 20 + &#39;px&#39;;
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h2 id="常用键盘事件"><a href="#常用键盘事件" class="headerlink" title="常用键盘事件"></a>常用键盘事件</h2><h3 id="常用键盘事件-1"><a href="#常用键盘事件-1" class="headerlink" title="常用键盘事件"></a>常用键盘事件</h3><table>
<thead>
<tr>
<th>键盘事件</th>
<th>触发条件</th>
</tr>
</thead>
<tbody><tr>
<td>onkeyup</td>
<td>某个键盘按键被松开时触发（松开的时候触发）</td>
</tr>
<tr>
<td>onkeydown</td>
<td>某个键盘按键被按下时触发（按下之后一直触发）</td>
</tr>
<tr>
<td>onkeypress</td>
<td>某个键盘按键被按下时触发（按下之后一直触发），但是它不能识别功能键，比如 ctrl、shift 等</td>
</tr>
</tbody></table>
<p>当按下的时候，keydown 执行在 keypress 之前。</p>
<h2 id="键盘事件对象"><a href="#键盘事件对象" class="headerlink" title="键盘事件对象"></a>键盘事件对象</h2><table>
<thead>
<tr>
<th>键盘事件对象属性</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>keyCode</td>
<td>返回该键的 ASCII 值</td>
</tr>
</tbody></table>
<p><strong>注意：</strong></p>
<ul>
<li>keyup 和 keydown 事件不区分字母大小写， a 和 A 得到的都是65</li>
<li>keypress 区分大小写，a 得到的是97，A 得到的是 65</li>
</ul>
<h3 id="案例1"><a href="#案例1" class="headerlink" title="案例1:"></a>案例1:</h3><p>京东按下 s 键定位到搜索框:</p>
<p>检测用户是否按下了 s 键盘，如果按下 s 键，就把光标定位到搜索框里面。</p>
<h4 id="案例分析-1"><a href="#案例分析-1" class="headerlink" title="案例分析"></a>案例分析</h4><ul>
<li>利用键盘事件对象里面的 keyCode 判断用户是否按下的是 s 键</li>
<li>搜索框获得焦点的方法: 利用 js 里面的 focus() 方法</li>
</ul>
<pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;title&gt;京东搜索框&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;input type=&quot;text&quot; name=&quot;&quot; id=&quot;&quot;&gt;
    &lt;script&gt;
        var input = document.querySelector(&#39;input&#39;);
        document.addEventListener(&#39;keyup&#39;, function (e) {
            if (e.keyCode == 83) {
                input.focus();
            }
        });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<h3 id="案例2"><a href="#案例2" class="headerlink" title="案例2:"></a>案例2:</h3><p>快递单号查询:</p>
<p>查询快递单号的时候，上面一个更大的盒子显示同样的内容（这里的字号更大）。</p>
<p><img src="http://helloxx.cn/express.png" srcset="/myblog/img/loading.gif" alt="快递单号查询"></p>
<h4 id="案例分析-2"><a href="#案例分析-2" class="headerlink" title="案例分析"></a>案例分析</h4><ul>
<li>表单检测用户输入：给表单添加键盘事件</li>
<li>同时把快递单号里面的值（value）获取过来赋值给 con 盒子（innerText）作为内容</li>
<li>当失去焦点的时候，就隐藏这个 con 盒子。</li>
<li>当获得焦点的时候，如果快递单号里面不为空，就显示 con 盒子。</li>
</ul>
<pre><code class="html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;style&gt;
    .search {
        position: relative;
        width: 178px;
        margin: 100px;
    }
    .con {
        display: none;;
        position: absolute;
        top: -40px;
        width: 171px;
        border: 1px solid rgba(0, 0, 0, 0.2);
        padding: 5px 0;
        font-size: 18px;
        line-height: 20px;
        color: #333;
    }
    .con::before {
        content: &#39;&#39;;
        width: 0;
        height: 0;
        position: absolute;
        top: 28px;
        left: 18px;
        border: 8px solid #000;
        border-style: solid dashed dashed;
        border-color: #fff transparent transparent;
    }
    &lt;/style&gt;
&lt;/head&gt;

&lt;body&gt;
    &lt;div class=&quot;search&quot;&gt;
        &lt;div class=&quot;con&quot;&gt;123&lt;/div&gt;
        &lt;input type=&quot;text&quot; placeholder=&quot;请输入您的快递单号&quot;&gt;
    &lt;/div&gt;
    &lt;script&gt;
    var input = document.querySelector(&#39;input&#39;);
    var con = document.querySelector(&#39;.con&#39;);
    input.addEventListener(&#39;keyup&#39;, function(e) {
        if (this.value == &#39;&#39;) {
            con.style.display = &#39;none&#39;;
        } else {
            con.style.display = &#39;block&#39;;
            con.innerText = this.value;
        }
    });
    // 当失去焦点的时候，就隐藏这个 con 盒子。
    input.addEventListener(&#39;blur&#39;, function() {
        con.style.display = &#39;none&#39;;
    });
    // 当获得焦点的时候，如果内容不为空，就显示这个 con 盒子。
    input.addEventListener(&#39;focus&#39;, function() {
        if (this.value !== &#39;&#39;) {
            con.style.display = &#39;block&#39;;
        }
    });
    &lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><strong>注意：</strong></p>
<p>keydown 和 keypress 触发的时候，文字还没有落入文本框中。</p>
<p>keyup 触发的时候，文字已经输入到文本框中。</p>
<h1 id="BOM"><a href="#BOM" class="headerlink" title="BOM"></a>BOM</h1><h2 id="BOM导读"><a href="#BOM导读" class="headerlink" title="BOM导读"></a>BOM导读</h2><p>BOM(Brower Object Model) 即<strong>浏览器对象模型</strong>，它提供了独立于内容而与<strong>浏览器窗口进行交互的对象</strong>，其核心对象是window。</p>
<p>BOM 是由一系列相关的对象构成，并且每个对象都提供了很多方法和属性。</p>
<p>BOM 缺乏标准，JavaScript 语法的标准化组织是 ECMA，DOM 的标准化组织是 W3C，BOM 最初是 Netscape 浏览器标准的一部分。每个浏览器都有自己的标准。</p>
<h2 id="BOM-的组成："><a href="#BOM-的组成：" class="headerlink" title="BOM 的组成："></a>BOM 的组成：</h2><p>BOM 比 DOM 更大，它包括 DOM。</p>
<pre><code class="mermaid">graph TD
A[window] --&gt;B(document)
A[window] --&gt;C(location)
A[window] --&gt;D(navigation)
A[window] --&gt;E(screen)
A[window] --&gt;F(history)</code></pre>
<p>window 对象是浏览器的顶级对象，它具有双重角色。</p>
<ul>
<li>它是 JS 访问浏览器窗口的一个接口。</li>
<li>它是一个全局对象，定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法。</li>
</ul>
<p>在调用的时候可以省略 window，前面学习的对话框都属于 window 对象方法，如 alert()、prompt() 等。</p>
<h2 id="window-对象的常见事件"><a href="#window-对象的常见事件" class="headerlink" title="window 对象的常见事件"></a>window 对象的常见事件</h2><h3 id="窗口加载事件"><a href="#窗口加载事件" class="headerlink" title="窗口加载事件"></a>窗口加载事件</h3><h4 id="窗口加载事件-1"><a href="#窗口加载事件-1" class="headerlink" title="窗口加载事件"></a>窗口加载事件</h4><pre><code class="javascript">window.onload = function() {}
或者
window.addEventListener(&quot;load&quot;,function(){});</code></pre>
<p>window.onload 是窗口（页面）加载事件，当文档内容完全加载完成后会触发该事件（包括图像、脚本文件、CSS文件等）。</p>
<p>window.onload 只能写一次，当写了很多个的时候，只有最后一个起作用， 所以推荐第二种写法。</p>
<h4 id="DOM加载事件"><a href="#DOM加载事件" class="headerlink" title="DOM加载事件"></a>DOM加载事件</h4><pre><code class="javascript">window.addEventListener(&quot;DOMContentLoaded&quot;,function(){});</code></pre>
<p>这个事件当 DOM 加载完成时触发，不包含 CSS、图片、flash 等。</p>
<p>IE9+ 支持。</p>
<h3 id="调整窗口大小事件"><a href="#调整窗口大小事件" class="headerlink" title="调整窗口大小事件"></a>调整窗口大小事件</h3><pre><code class="javascript">window.onresize = function() {}
或者
window.addEventListener(&quot;resize&quot;,function(){});</code></pre>
<p>这是调整窗口大小的时候的触发事件。包括窗口高度和宽度。</p>
<p>经常用来实现响应式布局。 window.inner.width 当前屏幕的宽度</p>
<h3 id="定时器"><a href="#定时器" class="headerlink" title="定时器"></a>定时器</h3><p>window 对象提供了2个好用的方法——定时器：</p>
<ul>
<li>setTimeout()</li>
<li>setInterval()</li>
</ul>
<pre><code class="javascript">window.setTimeout(调用函数， [延迟的毫秒数])；</code></pre>
<ul>
<li>setTimeout() 方法用于设置一个定时器，该定时器在定时器到期后执行调用函数。</li>
<li>这个 window 在调用的时候可以省略。</li>
<li>这个延时时间单位是毫秒，可以省略，如果省略默认是0。</li>
<li>这个调用函数可以直接写函数，还可以写函数名，<strong>函数名后面不写括号</strong>。</li>
<li>页面中可能有很多的定时器，我们经常给定时器加标识符（名字）。</li>
</ul>
<h3 id="停止-setTimeout-定时器"><a href="#停止-setTimeout-定时器" class="headerlink" title="停止 setTimeout() 定时器"></a>停止 setTimeout() 定时器</h3><pre><code class="javascript">window.clearTimeout(timeoutID)</code></pre>
<ul>
<li>window 可以省略</li>
<li>里面的参数是定时器的标识符</li>
</ul>
<h3 id="setInterval-定时器"><a href="#setInterval-定时器" class="headerlink" title="setInterval() 定时器"></a>setInterval() 定时器</h3><pre><code class="javascript">window.setInterval(调用函数， [延迟的毫秒数])；</code></pre>
<p>setInterval() 方法重复调用一个函数，每隔这个时间，就去调用一次回调函数</p>
<h3 id="倒计时效果"><a href="#倒计时效果" class="headerlink" title="倒计时效果"></a>倒计时效果</h3><p>分析：</p>
<ul>
<li>这个倒计时是不断变化的，所以使用 setInterval() 来实现</li>
<li>三个黑色盒子里面分别放时分秒</li>
<li>三个黑子盒子的利用 innerHTML 放入计算的小时分钟秒数</li>
<li>第一次之前也是间隔一定的毫秒数，所以在定时器的前面先调用一下刷新时间的函数，防止第一次刷新之前有空白</li>
</ul>
<pre><code class="html">&lt;body&gt;
    &lt;div&gt;
        &lt;span class=&quot;hour&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;minute&quot;&gt;2&lt;/span&gt;
        &lt;span class=&quot;second&quot;&gt;3&lt;/span&gt;
    &lt;/div&gt;
    &lt;script&gt;
    var hour = document.querySelector(&#39;.hour&#39;);
    var minute = document.querySelector(&#39;.minute&#39;);
    var second = document.querySelector(&#39;.second&#39;);
    var inputTime = +new Date(&#39;2019-9-22 18:00:00&#39;);
    // 在定时器获取之前，先运行一次，这样不会显示原始默认的1 2 3
    getInterval();
    // 每秒钟获取一次事件
    setInterval(getInterval, 1000);
    function getInterval() {
            var nowTime = +new Date();
            var interval = (inputTime - nowTime) / 1000;     //两个日期相差的秒数
            var hours, minutes, seconds;
            hours =  Math.floor(interval / 60 / 60 % 24);
            hours = hours &lt; 10 ? &#39;0&#39; + hours : hours;
            hour.innerHTML = hours;
            minutes =  Math.floor(interval / 60 % 60);
            minutes = minutes &lt; 10 ? &#39;0&#39; + minutes : minutes;
            minute.innerHTML = minutes;
            seconds =  Math.floor(interval % 60);
            seconds = seconds &lt; 10 ? &#39;0&#39; + seconds : seconds;
            second.innerHTML = seconds;
        }
    &lt;/script&gt;
&lt;/body&gt;</code></pre>
<h3 id="清除定时器"><a href="#清除定时器" class="headerlink" title="清除定时器"></a>清除定时器</h3><pre><code class="javascript">window.clearInterval(intervalID)；</code></pre>
<ul>
<li>window 可以省略</li>
<li>里面的参数是定时器的标识符</li>
</ul>
<pre><code class="html">&lt;body&gt;
    &lt;button class=&quot;begin&quot;&gt;开始定时器&lt;/button&gt;
    &lt;button class=&quot;stop&quot;&gt;结束定时器&lt;/button&gt;
    &lt;script&gt;
        var i = 1;
        var begin = document.querySelector(&#39;.begin&#39;);
        var stop = document.querySelector(&#39;.stop&#39;);
        var timer = null; //全局变量，null 是一个空对象
        begin.addEventListener(&#39;click&#39;, function() {
            timer = setInterval(function() {
                console.log(&#39;你好啊&#39; + i);
                i = i + 1;
            }, 1000);
        });
        stop.addEventListener(&#39;click&#39;, function() {
            clearInterval(timer);
        });
    &lt;/script&gt;
&lt;/body&gt;</code></pre>
<h3 id="发送短信案例"><a href="#发送短信案例" class="headerlink" title="发送短信案例"></a>发送短信案例</h3><p>点击发送验证码之后，该按钮在60秒只能不能再被点击，防止重复发送短信</p>
<h4 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h4><ul>
<li>点击按钮之后，将按钮禁用，disable 为 true</li>
<li>一秒钟修改一次 button 里面的内容</li>
<li>定义一个变量为秒数，这个数值定时变化，如果为0，说明时间到，按钮恢复原始状态</li>
</ul>
<pre><code class="html">&lt;body&gt;
    手机号码：
    &lt;input type=&quot;number&quot; name=&quot;&quot; id=&quot;&quot;&gt;
    &lt;button&gt;发送&lt;/button&gt;
    &lt;script&gt;
        var btn = document.querySelector(&#39;button&#39;);
        btn.addEventListener(&#39;click&#39;, function() {
            btn.disabled = true;
            var i = 60;
            var timer = setInterval(function() {
                if (i == 0) {
                    clearInterval(timer);
                    btn.disabled = false;
                    btn.innerHTML = &#39;发送验证码&#39;;
                    i = 60;
                } else {
                    btn.innerHTML = i + &#39;秒之后可以再次点击&#39;;
                    i--;
                }
            }, 1000);
        });
    &lt;/script&gt;
&lt;/body&gt;</code></pre>
<h3 id="this-的指向问题"><a href="#this-的指向问题" class="headerlink" title="this 的指向问题"></a>this 的指向问题</h3><p>this 的指向在函数定义的时候是确定不了的，只有函数执行的时候才能确定 this 到底指向谁，一般情况下 this 的最终指向的是那个调用它的对象。</p>
<h2 id="JS-执行队列"><a href="#JS-执行队列" class="headerlink" title="JS 执行队列"></a>JS 执行队列</h2><p>JS 的一大特点就是单线程，也就是说，同一时间只能做一件事，这是因为 JS这门语言诞生的使命导致的—— JS 是为处理页面中用户的交互，以及操作 DOM 而诞生的。比如我们对某个 DOM 元素进行添加和删除操作，不能同时进行。应该先添加，然后再删除。</p>
<p>单线程就意味着，所有任务需要排队，前一个任务结束，才会执行后一个任务。这样所导致的问题是：如果JS执行的时间过长，这样就会造成页面的渲染不连贯，导致页面渲染加载阻塞的感觉。</p>
<h3 id="同步和异步"><a href="#同步和异步" class="headerlink" title="同步和异步"></a>同步和异步</h3><p>为了解决这个问题，利用多核 CPU 的计算能力，HTML5 提出 Web Worker 标准，允许 JavaScript 脚本创建多个线程。于是，JS 中出现了 <strong>同步</strong> 和 <strong>异步</strong> 。</p>
<pre><code class="javascript">    &lt;script&gt;
        console.log(1);
        setTimeout(function () {
            console.log(3);
        }, 1000);
        console.log(2);
    &lt;/script&gt;</code></pre>
<p>运行结果是 1  2  3</p>
<pre><code class="javascript">    &lt;script&gt;
        console.log(1);
        setTimeout(function () {
            console.log(3);
        }, 0);
        console.log(2);
    &lt;/script&gt;</code></pre>
<p>运行结果是 1  2  3</p>
<p><strong>同步任务</strong>：同步任务都在主线程上执行，形成一个执行栈。</p>
<p><strong>异步任务</strong>： JS 的异步是通过回调函数实现的。</p>
<p>一般而言，异步任务有以下三种类型：</p>
<ol>
<li>普通事件：如click、resize 等</li>
<li>资源加载，如load、error 等</li>
<li>定时器，包括setInterval、setTimeout 等</li>
</ol>
<p>异步任务相关回调函数添加到任务队列中（任务队列也称为消息队列）。</p>
<h3 id="JS-的执行机制"><a href="#JS-的执行机制" class="headerlink" title="JS 的执行机制"></a>JS 的执行机制</h3><ol>
<li>先执行执行栈中的同步任务。</li>
<li>异步任务（回调函数）放入任务队列中。</li>
<li>一旦执行栈中所有同步任务完成，系统就会按次序读取任务队列中的异步任务，于是被读取的异步任务结束等待状态，进入执行栈，开始执行。</li>
</ol>
<p>由于主现程不断地重复获得任务、执行任务、再获取任务、再执行，所以这种机制被称为<strong>事件循环（evwnt loop）</strong>。</p>
<h2 id="location-对象"><a href="#location-对象" class="headerlink" title="location 对象"></a>location 对象</h2><p>window 对象给我们提供了一个 location 属性用于获取或设置窗体的URL，并且可以用于解析URL。因为这个属性返回的是一个对象，所以我们将这个属性也称为 location 对象。</p>
<h3 id="URL"><a href="#URL" class="headerlink" title="URL"></a>URL</h3><p>统一资源定位符（Uniform Resource Locator，URL）是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL，它包含的信息指出文件的位置以及浏览器应该怎么处理它。</p>
<p>URL 的一般语法结构为：</p>
<pre><code>porotocol：//host[:port]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&amp;age=18#link</code></pre><table>
<thead>
<tr>
<th>组成</th>
<th>说明</th>
</tr>
</thead>
<tbody><tr>
<td>protocol</td>
<td>通信协议，常用的http、ftp、maito等</td>
</tr>
<tr>
<td>host</td>
<td>主机（域名）</td>
</tr>
<tr>
<td>port</td>
<td>端口号，可选，省略时使用默认断开，如http的默认端口80</td>
</tr>
<tr>
<td>path</td>
<td>路径，由零或多个“/”格开的字符串，一般用来表示主机上的一个目录或者文件地址</td>
</tr>
<tr>
<td>query</td>
<td>参数，以键值对的形式，通过符号 &amp; 分割开来</td>
</tr>
<tr>
<td>fragment</td>
<td>片段，# 后面的内容常见于链接，锚点</td>
</tr>
</tbody></table>
<h3 id="location-对象的属性"><a href="#location-对象的属性" class="headerlink" title="location 对象的属性"></a>location 对象的属性</h3><table>
<thead>
<tr>
<th>location 对象属性</th>
<th>返回值</th>
</tr>
</thead>
<tbody><tr>
<td>location.href</td>
<td>获取或者设置整个 URL</td>
</tr>
<tr>
<td>location.host</td>
<td>返回主机（域名）</td>
</tr>
<tr>
<td>location.port</td>
<td>返回端口号，如果未写返回空字符串</td>
</tr>
<tr>
<td>location.pathname</td>
<td>返回路径</td>
</tr>
<tr>
<td>location.search</td>
<td>返回参数</td>
</tr>
<tr>
<td>location.hash</td>
<td>返回片段，# 后面内容，常见于链接、锚点</td>
</tr>
</tbody></table>
<h4 id="5秒钟之后自动跳转页面"><a href="#5秒钟之后自动跳转页面" class="headerlink" title="5秒钟之后自动跳转页面"></a>5秒钟之后自动跳转页面</h4><p>案例分析：</p>
<ul>
<li>利用定时器做倒计时效果</li>
<li>location.href 跳转页面</li>
</ul>
<pre><code class="html">    &lt;div&gt;将在5秒钟之后跳转到首页！&lt;/div&gt;
    &lt;script&gt;
        setTimeout(function() {
            location.href = &#39;http://www.baidu.com&#39;;
        }, 5000);
    &lt;/script&gt;</code></pre>
<h4 id="获取-URL-参数数据"><a href="#获取-URL-参数数据" class="headerlink" title="获取 URL 参数数据"></a>获取 URL 参数数据</h4><p>主要练习数据在不同页面之间的传递</p>
<p>案例分析：</p>
<ul>
<li>第一个登陆页面，里面有提交表单，action 提交到 index.html 页面</li>
<li>第二个页面可以使用第一个页面的参数，利用了 location.search 参数</li>
<li>截取字符串用 substr</li>
<li>分隔符，将 = 前后的分隔开</li>
</ul>
<p>login.html :</p>
<pre><code class="html">&lt;form action=&quot;index.html&quot;&gt;
    &lt;input type=&quot;text&quot; name=&quot;username&quot; id=&quot;&quot;&gt;
    &lt;input type=&quot;submit&quot; value=&quot;登录&quot;&gt;
&lt;/form&gt;</code></pre>
<p>index.html :</p>
<pre><code class="html">&lt;div&gt;&lt;/div&gt;
&lt;script&gt;
    // substr(起始位置, 截取几个字符)
    var params = location.search.substr(1);
    var arr = params.split(&#39;=&#39;);
    var div = document.querySelector(&#39;div&#39;);
    div.innerHTML = &#39;欢迎您！会员&#39; + arr[1] + &#39;！&#39;;
&lt;/script&gt;</code></pre>
<h3 id="location-常见方法"><a href="#location-常见方法" class="headerlink" title="location 常见方法"></a>location 常见方法</h3><table>
<thead>
<tr>
<th>location 对象方法</th>
<th>返回值</th>
</tr>
</thead>
<tbody><tr>
<td>location.assign()</td>
<td>跟 href 一样，可以跳转页面</td>
</tr>
<tr>
<td>location.replace()</td>
<td>替换当前页面，因为不记录历史，所以不能后退页面</td>
</tr>
<tr>
<td>location.reload()</td>
<td>重新加载页面，相当于刷新按钮或者 F5，如果参数为true，强制刷新 ctrl + F5</td>
</tr>
</tbody></table>
<h2 id="navigator-对象"><a href="#navigator-对象" class="headerlink" title="navigator 对象"></a>navigator 对象</h2><p>navigator对象包含有关浏览器的信息，它有很多属性，我们最常用的是userAgent，该属性可以返回由客户机发送服务器的useragent头部的值。</p>
<h2 id="history-对象"><a href="#history-对象" class="headerlink" title="history 对象"></a>history 对象</h2><p>window对象给我们提供了一个history对象，与浏览器历史记录进行交互。该对象包含用户（在浏览器窗口中）访问过的URL。</p>
<table>
<thead>
<tr>
<th>history 对象方法</th>
<th>作用</th>
</tr>
</thead>
<tbody><tr>
<td>back()</td>
<td>后退功能</td>
</tr>
<tr>
<td>forward()</td>
<td>前进功能</td>
</tr>
<tr>
<td>go(参数)</td>
<td>前进后退功能，参数如果是1，前进一个页面，如果是-1，后退一个页面</td>
</tr>
</tbody></table>
<p>history 对象在一般的实际开发中比较少用，但是会在一些 OA 办公系统中见到。</p>

            </div>
            <hr>
            <div>
              <p>
                
                
              </p>
              
                <p class="note note-warning">本博客所有文章除特别声明外，均采用 <a href="https://zh.wikipedia.org/wiki/Wikipedia:CC_BY-SA_3.0%E5%8D%8F%E8%AE%AE%E6%96%87%E6%9C%AC" target="_blank" rel="nofollow noopener noopener">CC BY-SA 3.0协议</a> 。转载请注明出处！</p>
              
              
                <div class="post-prevnext row">
                  <div class="post-prev col-6">
                    
                    
                      <a href="/myblog/2019/04/15/JavaScript%E8%BF%9B%E9%98%B6%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1ES6%E7%AC%94%E8%AE%B0/">
                        <i class="fa fa-chevron-left"></i>
                        <span class="hidden-mobile">JavaScript高级&ES6 学习笔记</span>
                        <span class="visible-mobile">上一篇</span>
                      </a>
                    
                  </div>
                  <div class="post-next col-6">
                    
                    
                      <a href="/myblog/2019/03/10/JavaScript%E5%9F%BA%E7%A1%80%E8%AF%AD%E6%B3%95/">
                        <span class="hidden-mobile">JavaScript基础学习笔记</span>
                        <span class="visible-mobile">下一篇</span>
                        <i class="fa fa-chevron-right"></i>
                      </a>
                    
                  </div>
                </div>
              
            </div>

              
          </div>
        </div>
      </div>
    </div>
    
      <div class="d-none d-lg-block col-lg-2 toc-container" id="toc-ctn">
        <div id="toc-start"></div>
<div id="toc">
  <p class="h5"><i class="far fa-list-alt"></i>&nbsp;目录</p>
  <div id="tocbot"></div>
</div>

      </div>
    
  </div>
</div>

<!-- Custom -->


    
  </main>

  
    <a class="z-depth-1" id="scroll-top-button" href="#" role="button">
      <i class="fa fa-chevron-up scroll-top-arrow" aria-hidden="true"></i>
    </a>
  

  
    <div class="modal fade" id="modalSearch" tabindex="-1" role="dialog" aria-labelledby="ModalLabel"
     aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable modal-lg" role="document">
    <div class="modal-content">
      <div class="modal-header text-center">
        <h4 class="modal-title w-100 font-weight-bold">搜索</h4>
        <button type="button" id="local-search-close" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body mx-3">
        <div class="md-form mb-5">
          <input type="text" id="local-search-input" class="form-control validate">
          <label data-error="x" data-success="v"
                 for="local-search-input">关键词</label>
        </div>
        <div class="list-group" id="local-search-result"></div>
      </div>
    </div>
  </div>
</div>
  

  

  

  <footer class="mt-5">
  <div class="text-center py-3">
    <div>
      <a href="https://hexo.io" target="_blank" rel="nofollow noopener"><b>Hexo</b></a>
      <i class="iconfont icon-love"></i>
      <a href="https://github.com/fluid-dev/hexo-theme-fluid" target="_blank" rel="nofollow noopener"> <b>Fluid</b></a>
    </div>
    

    

    
  </div>
</footer>

<!-- SCRIPTS -->
<script  src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js" ></script>
<script  src="https://cdn.staticfile.org/popper.js/1.16.1/umd/popper.min.js" ></script>
<script  src="https://cdn.staticfile.org/twitter-bootstrap/4.4.1/js/bootstrap.min.js" ></script>
<script  src="https://cdn.staticfile.org/mdbootstrap/4.13.0/js/mdb.min.js" ></script>
<script  src="/myblog/js/main.js" ></script>


  <script  src="/myblog/js/lazyload.js" ></script>



  
  <script  src="https://cdn.staticfile.org/tocbot/4.10.0/tocbot.min.js" ></script>
  <script>
    $(document).ready(function () {
      var navHeight = $('#navbar').height();
      var toc = $('#toc');
      var boardCtn = $('#board-ctn');
      var boardTop = boardCtn.offset().top;
      var tocLimMax = 2 * boardTop + boardCtn.height();

      $(window).scroll(function () {
        var tocLimMin = $('#toc-start').offset().top - navHeight;
        var scroH = document.body.scrollTop + document.documentElement.scrollTop;

        if (tocLimMin <= scroH && scroH <= tocLimMax) {
          toc.css({
            'display': 'block',
            'position': 'fixed',
            'top': navHeight,
          });
        } else if (scroH <= tocLimMin) {
          toc.css({
            'position': '',
            'top': '',
          });
        } else if (scroH > tocLimMax) {
          toc.css('display', 'none');
        }
      });
      tocbot.init({
        tocSelector: '#tocbot',
        contentSelector: '.post-content',
        headingSelector: 'h1,h2,h3,h4,h5,h6',
        linkClass: 'tocbot-link',
        activeLinkClass: 'tocbot-active-link',
        listClass: 'tocbot-list',
        isCollapsedClass: 'tocbot-is-collapsed',
        collapsibleClass: 'tocbot-is-collapsible',
        scrollSmooth: true,
        headingsOffset: -boardTop
      });
      if ($('.toc-list-item').length > 0) {
        $('#toc > p').css('visibility', 'visible');
      }
      var offset = boardCtn.css('margin-right')
      $('#toc-ctn').css({
        'right': offset
      })
    });
  </script>





  <script defer src="https://cdn.staticfile.org/clipboard.js/2.0.6/clipboard.min.js" ></script>
  <script  src="/myblog/js/clipboard-use.js" ></script>








<!-- Plugins -->



  <script  src="https://cdn.staticfile.org/prettify/188.0.0/prettify.min.js" ></script>
  <script>
    $(document).ready(function () {
      $('pre').addClass('prettyprint  linenums');
      prettyPrint();
    })
  </script>



  <script  src="https://cdn.staticfile.org/typed.js/2.0.11/typed.min.js" ></script>
  <script>
    var typed = new Typed('#subtitle', {
      strings: [
        '  ',
        "JS DOM BOM操作&nbsp;",
      ],
      cursorChar: "_",
      typeSpeed: 70,
      loop: false,
    });
    typed.stop();
    $(document).ready(function () {
      $(".typed-cursor").addClass("h2");
      typed.start();
    });
  </script>



  <script  src="https://cdn.staticfile.org/anchor-js/4.2.2/anchor.min.js" ></script>
  <script>
    anchors.options = {
      placement: "right",
      visible: "hover",
      
    };
    var el = "h1,h2,h3,h4,h5,h6".split(",");
    var res = [];
    for (item of el) {
      res.push(".markdown-body > " + item)
    }
    anchors.add(res.join(", "))
  </script>



  <script  src="/myblog/js/local-search.js" ></script>
  <script>
    var path = "/myblog/local-search.xml";
    var inputArea = document.querySelector("#local-search-input");
    inputArea.onclick = function () {
      getSearchFile(path);
      this.onclick = null
    }
  </script>



  <script defer src="https://cdn.staticfile.org/fancybox/3.5.7/jquery.fancybox.min.js" ></script>
  <script>
    $("#post img:not(.no-zoom img, img[no-zoom])").each(
      function () {
        var element = document.createElement("a");
        $(element).attr("data-fancybox", "images");
        $(element).attr("href", $(this).attr("src"));
        $(this).wrap(element);
      }
    );
  </script>












</body>
</html>
